<!doctype html>
<head>
<meta charset=utf-8>
<title>Tests for setting spacing by using KeyframeEffect.spacing</title>
<script src='../testcommon.js'></script>
</head>
<body>
<script>
'use strict';

function calculateInterpolation(pacedDistances, values, progress) {
  if (progress == 0.0) {
    return values[0];
  } else if (progress == 1.0) {
    return values[valus.length - 1];
  }

  const cumDist = pacedDistances.reduce( (prev, curr) => {
    prev.push(prev.length == 0 ? curr : curr + prev[prev.length - 1]);
    return prev;
  }, []);

  const last = cumDist[cumDist.length - 1];
  const offsets = cumDist.map( (curr) => { return curr / last; } );

  let idx = 0;
  for (let i = 0; i < offsets.length - 1; ++i) {
    if (progress >= offsets[i] && progress < offsets[i + 1]) {
      idx = i;
      break;
    }
  }

  const ratio = (progress - offsets[idx]) / (offsets[idx + 1] - offsets[idx]);
  return values[idx] + ratio * (values[idx + 1] - values[idx]) + 'px';
}

promise_test(function(t) {
  var target = addDiv(t);
  var anim = target.animate([ { marginLeft: '0px' },
                              { marginLeft: '-20px' },
                              { marginLeft: '100px' },
                              { marginLeft: '50px' } ],
                            100 * MS_PER_SEC);

  return anim.ready.then(function() {
    anim.currentTime = 50 * MS_PER_SEC;
    assert_equals(getComputedStyle(target).marginLeft, '40px',
                  'computed value before setting a new spacing');

    var dist = [0, 20, 120, 50];
    var marginLeftValues = [0, -20, 100, 50];
    anim.effect.spacing = 'paced(margin-left)';
    assert_equals(getComputedStyle(target).marginLeft,
                  calculateInterpolation(dist, marginLeftValues, 0.5),
                  'computed value after setting a new spacing');
  });
}, 'Test for setting spacing from distribute to paced');

promise_test(function(t) {
  var target = addDiv(t);
  var anim = target.animate([ { marginLeft: '0px' },
                              { marginLeft: '-20px' },
                              { marginLeft: '100px' },
                              { marginLeft: '50px' } ],
                            { duration: 100 * MS_PER_SEC,
                              spacing: 'paced(margin-left)' });

  return anim.ready.then(function() {
    var dist = [0, 20, 120, 50];
    var marginLeftValues = [0, -20, 100, 50];
    anim.currentTime = 50 * MS_PER_SEC;
    assert_equals(getComputedStyle(target).marginLeft,
                  calculateInterpolation(dist, marginLeftValues, 0.5),
                  'computed value before setting a new spacing');

    anim.effect.spacing = 'distribute';
    assert_equals(getComputedStyle(target).marginLeft, '40px',
                  'computed value after setting a new spacing');
  });
}, 'Test for setting spacing from paced to distribute');

promise_test(function(t) {
  var target = addDiv(t);
  var anim =
    target.animate([ { marginLeft: '0px', borderRadius: '0%' },
                     { marginLeft: '-20px', borderRadius: '50%' },
                     { marginLeft: '100px', borderRadius: '25%' },
                     { marginLeft: '50px', borderRadius: '100%' } ],
                   { duration: 100 * MS_PER_SEC,
                     spacing: 'paced(margin-left)' });

  return anim.ready.then(function() {
    var dist = [0, 20, 120, 50];
    var marginLeftValues = [0, -20, 100, 50];
    anim.currentTime = 50 * MS_PER_SEC;
    assert_equals(getComputedStyle(target).marginLeft,
                  calculateInterpolation(dist, marginLeftValues, 0.5),
                  'computed value before setting a new spacing');

    dist = [0, 50, 25, 75];
    anim.effect.spacing = 'paced(border-radius)';
    assert_equals(getComputedStyle(target).marginLeft,
                  calculateInterpolation(dist, marginLeftValues, 0.5),
                  'computed value after setting a new spacing');
  });
}, 'Test for setting spacing from paced to a different paced');

done();
</script>
</body>
